package com.inno.screenrecorder;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;

import com.inno.screenrecordhelper.FloatingWindowHelper;
import com.inno.screenrecordhelper.VideoRecordManager;

import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;


/**
 * 参考：https://cloud.tencent.com/developer/article/1384728
 */
public class MainActivity2 extends AppCompatActivity implements MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener {
    private static final String TAG = "111";
    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    private Camera camera;
    private MediaRecorder videoRecorder;
    private String myVideofilepath = "sdcard/myvideo.3gp";

    public static final int VIDEO_RECORD = 1;//视频录制
    public static final int AUDIO_RECORD = 2;//音频录制
    private boolean mServiceBound;
    private File mRecordFile;
    private Timer mTimer;  //计时器
    private int mTimeCount;  //时间计数
    private int curType;
    private Intent intent;
    private VideoRecordManager videoRecordManager;

    /*
     * 开启悬浮Video服务
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startVideoService() {
        if (FloatingWindowHelper.canDrawOverlays(this, true)) {
            intent = new Intent(this, FloatWindowService.class);
            startForegroundService(intent);
//                stopService(intent);
        }

    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        surfaceView = findViewById(R.id.surface);
        startVideoService();
//        surfaceHolder = surfaceView.getHolder();
//        videoRecorder = new MediaRecorder();
//        init();
        videoRecordManager = new VideoRecordManager(surfaceView, new VideoRecordManager.OnVideoRecordListener() {
            @Override
            public void onBeforeRecord() {

            }

            @Override
            public void onStartRecord() {

            }

            @Override
            public void onCancelRecord() {

            }

            @Override
            public void onEndRecord() {

            }
        });
        findViewById(R.id.btn_open_float).setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onClick(View v) {

            }
        });
        findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onClick(View v) {
                if (FloatWindowService.isStart) {
                    LocalBroadcastManager.getInstance(MainActivity2.this)
                            .sendBroadcast(new Intent(FloatWindowService.ACTION_AUDIO_VIDEO));
                } else {
                    startVideoService();
                }

//                videoRecordManager.record(VideoRecordManager.VIDEO_RECORD);
//                videoRecordManager.setCurType(VideoRecordManager.VIDEO_RECORD);
//                curType = VIDEO_RECORD;
            }
        });
        findViewById(R.id.btn_stop).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LocalBroadcastManager.getInstance(MainActivity2.this)
                        .sendBroadcast(new Intent(FloatWindowService.STOP_VIDEO));
//                videoRecordManager.stop(VideoRecordManager.VIDEO_RECORD);
            }
        });

        findViewById(R.id.btn_audio_start).setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onClick(View v) {
                if (FloatWindowService.isStart) {
                    LocalBroadcastManager.getInstance(MainActivity2.this)
                            .sendBroadcast(new Intent(FloatWindowService.ACTION_AUDIO));
                } else {
                    startVideoService();
                }

//                videoRecordManager.record(VideoRecordManager.AUDIO_RECORD);
//                videoRecordManager.setCurType(VideoRecordManager.AUDIO_RECORD);
//                curType = AUDIO_RECORD;
            }
        });

        findViewById(R.id.btn_audio_stop).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LocalBroadcastManager.getInstance(MainActivity2.this)
                        .sendBroadcast(new Intent(FloatWindowService.STOP_AUDIO));

            }
        });

        findViewById(R.id.btn_screen_start).setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onClick(View v) {
                if (FloatWindowService.isStart) {
                    startScreenShot(FloatWindowService.REQUEST_CODE);
                } else {
                    startVideoService();
                }
            }
        });

        findViewById(R.id.btn_screen_stop).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LocalBroadcastManager.getInstance(MainActivity2.this)
                        .sendBroadcast(new Intent(FloatWindowService.STOP_SCREEN));
            }
        });

        findViewById(R.id.btn_all_start).setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onClick(View v) {
                if (FloatWindowService.isStart) {
                    startScreenShot(FloatWindowService.REQUEST_CODE_ALL);
                } else {
                    startVideoService();
                }
            }
        });

        findViewById(R.id.btn_all_stop).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LocalBroadcastManager.getInstance(MainActivity2.this)
                        .sendBroadcast(new Intent(FloatWindowService.STOP_VIDEO_SCREEN));
            }
        });

        initScreen();
    }


    private void startScreenShot(int requestCode){
        if (mediaProjectionManager == null) {
            Log.d(TAG, "mediaProjectionManager == null，当前手机暂不支持录屏");
            showToast(com.inno.screenrecordhelper.R.string.phone_not_support_screen_record);
            return;
        }

//        if (null != listener) {
//            listener.onBeforeRecord();
//        }
        Intent intent = mediaProjectionManager.createScreenCaptureIntent();
        if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
            startActivityForResult(intent, requestCode);
        } else {
            showToast(com.inno.screenrecordhelper.R.string.phone_not_support_screen_record);
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == FloatWindowService.REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
//                mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
                Intent intent = new Intent(FloatWindowService.ACTION_AUDIO_SCREEN);
                intent.putExtra("code", Activity.RESULT_OK);
                intent.putExtra("data", data);
                LocalBroadcastManager.getInstance(MainActivity2.this)
                        .sendBroadcast(intent);
            } else {
                showToast(com.inno.screenrecordhelper.R.string.phone_not_support_screen_record);
            }
        }else if (requestCode == FloatWindowService.REQUEST_CODE_ALL) {
            if (resultCode == Activity.RESULT_OK) {
//                mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
                Intent intent = new Intent(FloatWindowService.ACTION_AUDIO_VIDEO_SCREEN);
                intent.putExtra("code", Activity.RESULT_OK);
                intent.putExtra("data", data);
                LocalBroadcastManager.getInstance(MainActivity2.this)
                        .sendBroadcast(intent);
            } else {
                showToast(com.inno.screenrecordhelper.R.string.phone_not_support_screen_record);
            }
        }
    }

    private void showToast(int resId) {
        Toast.makeText(this, getResources().getString(resId), Toast.LENGTH_SHORT).show();
    }

    private MediaProjectionManager mediaProjectionManager;
    public void initScreen() {
        mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
    }


    public void record(int type) {
        createRecordDir(type);
        try {
            if (type == VIDEO_RECORD) {
                initCamera();
            }

            initRecord(type);
            mTimeCount = 0;  //时间计数器重新赋值
            mTimer = new Timer();
            mTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    mTimeCount++;
                }
            }, 0, 1000);  //每隔1000毫秒就重复执行run函数
        } catch (Exception e) {
            Log.d(TAG, "record error: " + e.getMessage());
        }
    }

    //停止拍摄
    public void stop(int type) {
        stopRecord(type);
        releaseRecord();
        if (type == VIDEO_RECORD) {
            freeCameraResource();
        }

    }

    private void init() {
        surfaceHolder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
//                try {
//                    initCamera();
//                } catch (IOException e) {
//                    Log.d(TAG, "surfaceCreated error: " + e.getMessage());
//                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                if (curType == VIDEO_RECORD) {
                    freeCameraResource();
                }
            }
        });

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
//        stop(curType);
//        stopService(intent);
        videoRecordManager.onDestroy();
    }


    private void initRecord(int type) {
        videoRecorder = new MediaRecorder();
        videoRecorder.reset();
        if (camera != null && type == VIDEO_RECORD) {
            videoRecorder.setCamera(camera);
        }
        videoRecorder.setOnErrorListener(this);//设置错误监听器。可监听服务器异常以及未知错误的事件。
        videoRecorder.setOnInfoListener(this);//设置信息监听器。可监听录制结束事件，包括达到录制时长或者达到录制大小。
        if (type == VIDEO_RECORD) {
            videoRecorder.setPreviewDisplay(surfaceHolder.getSurface());
            videoRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);  //视频源
            videoRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  //音频源,一般使用麦克风
            //设置媒体输出格式OutputFormat.MPEG_4表示MPEG4格式，OutputFormat.THREE_GPP表示3GP格式。该方法要在setVideoEncoder之前调用。
            videoRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            //设置音频编码器。AudioEncoder.AMR_NB表示窄带编码，AudioEncoder.AMR_WB表示宽带编码，AudioEncoder.AAC表示低复杂度的高级编码，AudioEncoder.HE_AAC表示高效率的高级编码，
            videoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  //音频格式
            videoRecorder.setVideoSize(1920, 1080);  //设置分辨率：
            videoRecorder.setVideoFrameRate(24);  //setVideoFrameRate与setVideoEncodingBitRate设置其一即可
//        videoRecorder.setVideoEncodingBitRate(5 * 1024 * 512);  //设置帧频率，然后就清晰了
            videoRecorder.setOrientationHint(270);  //输出旋转90度，保持竖屏录制
            videoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);  //视频录制格式
//        videoRecorder.setMaxDuration(mRecordMaxTime * 1000);  //设置录制时长
//            videoRecorder.setMaxFileSize(1024*1024*10);  //setMaxFileSize与setMaxDuration设置其一即可
        } else {
            videoRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  //音频源,一般使用麦克风
            //设置媒体输出格式。OutputFormat.AMR_NB表示窄带格式，OutputFormat.AMR_WB表示宽带格式，AAC_ADTS表示高级的音频传输流格式。
            // 该方法要在setVideoEncoder之前调用，不然调用setAudioEncoder时会报错“java.lang.IllegalStateException”。
            videoRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            //设置音频编码器。AudioEncoder.AMR_NB表示窄带编码，AudioEncoder.AMR_WB表示宽带编码，AudioEncoder.AAC表示低复杂度的高级编码，AudioEncoder.HE_AAC表示高效率的高级编码，
            videoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  //音频格式
//            videoRecorder.setAudioSamplingRate();//设置音频的采样率，单位赫兹（Hz）。该方法为可选，AMRNB默认8khz，AMRWB默认16khz。
            videoRecorder.setAudioChannels(2);// : 设置音频的声道数。1表示单声道，2表示双声道。该方法为可选
            videoRecorder.setAudioEncodingBitRate(2 * 1024 * 512);// : 设置音频每秒录制的字节数。越大则音频越清晰。该方法为可选

        }

        videoRecorder.setOutputFile(mRecordFile.getAbsolutePath());
        try {
            videoRecorder.prepare();
            videoRecorder.start();
        } catch (Exception e) {
            Log.d(TAG, "MediaRecorder.start error: " + e.getMessage());
        }
    }

    public void initCamera() throws IOException {
        if (camera != null) {
            freeCameraResource();
        }
        try {
            camera = Camera.open(1);
        } catch (Exception e) {
            Log.d("111", "Camera.open() error: " + e.getMessage());
            freeCameraResource();
        }
        if (camera == null) {
            return;
        }
        setCameraParams();
        camera.setDisplayOrientation(90);
        camera.setPreviewDisplay(surfaceHolder);
        camera.startPreview();
        camera.unlock();
    }


    private void createRecordDir(int type) {
        File sampleDir = new File(Environment.getExternalStorageDirectory()
                + File.separator + "RecordVideo/");
        if (!sampleDir.exists()) {
            sampleDir.mkdirs();
        }
        File recordDir = sampleDir;
        try {
            if (type == VIDEO_RECORD) {
                mRecordFile = File.createTempFile("recording", ".mp4", recordDir);
            } else {
                mRecordFile = File.createTempFile("recording", ".mp3", recordDir);
            }

            Log.d(TAG, mRecordFile.getAbsolutePath());
        } catch (Exception e) {
            Log.d(TAG, "createTempFile error: " + e.getMessage());
        }
    }

    //设置摄像头为竖屏
    private void setCameraParams() {
        if (camera != null) {
            Camera.Parameters params = camera.getParameters();
            params.set("orientation", "portrait");
            camera.setParameters(params);
        }
    }

    private void freeCameraResource() {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.lock();
            camera.release();
            camera = null;
        }
    }

    private void stopRecord(int type) {
        if (mTimer != null) {
            mTimer.cancel();
        }
        if (videoRecorder != null) {
            videoRecorder.setOnErrorListener(null);
            videoRecorder.setPreviewDisplay(null);
            try {
                videoRecorder.stop();
            } catch (Exception e) {
                Log.d(TAG, "MediaRecorder.stop error: " + e.getMessage());
            }
        }
    }

    private void releaseRecord() {
        if (videoRecorder != null) {
            videoRecorder.setOnErrorListener(null);
            videoRecorder.release();
            videoRecorder = null;
        }
    }

    private boolean checkSDCard() {
        // 判断SD存储卡是否存在
        if (android.os.Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void onError(MediaRecorder mr, int what, int extra) {
        if (mr != null) {
            mr.reset();
        }
    }

    @Override
    public void onInfo(MediaRecorder mr, int what, int extra) {
        if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED
                || what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {

            //录制完成，
            Log.e(TAG, "onInfo: 录制完成");
        }
    }
}